\subsubsection{\OptimizingXcodeIV (\ThumbTwoMode)}

Domyślnie Xcode 4.6.3 generuje kod dla Thumb-2 wyglądający mniej więcej tak:

\begin{lstlisting}[caption=\OptimizingXcodeIV (\ThumbTwoMode),style=customasmARM]
__text:00002B6C                   _hello_world
__text:00002B6C 80 B5          PUSH            {R7,LR}
__text:00002B6E 41 F2 D8 30    MOVW            R0, #0x13D8
__text:00002B72 6F 46          MOV             R7, SP
__text:00002B74 C0 F2 00 00    MOVT.W          R0, #0
__text:00002B78 78 44          ADD             R0, PC
__text:00002B7A 01 F0 38 EA    BLX             _puts
__text:00002B7E 00 20          MOVS            R0, #0
__text:00002B80 80 BD          POP             {R7,PC}

...

__cstring:00003E70 48 65 6C 6C 6F 20+aHelloWorld  DCB "Hello world!",0xA,0
\end{lstlisting}

% Q: If you subtract 0x13D8 from 0x3E70,
% you actually get a location that is not in this function, or in _puts.
% How is PC-relative addressing done in THUMB2?
% A: it's not Thumb-related. there are just mess with two different segments. TODO: rework this listing.

\myindex{\ThumbTwoMode}
\myindex{ARM!\Instructions!BL}
\myindex{ARM!\Instructions!BLX}
Instrukcje \TT{BL} i \TT{BLX} w Thumb, są kodowane jako para 16-bitowych instrukcji, 
a w Thumb-2 te opcode są rozszerzone w ten sposób, że nowe instrukcje tutaj są kodowane jako 32-bitowe instrukcje.
Można to łatwo zauważyc, jako że w Thumb-2 instrukcje zaczynają się od \TT{0xFx} lub od \TT{0xEx}.
Ale w listingu \IDA bajty opcode są zamienione miejscami.
Dzieje się tak dlatego, że w procesorze ARM instrukcje są kodowane w ten sposób:
najpierw podaje się ostatni bajt, potem pierwszy (dla trybów Thumb i Thumb-2), lub, 
(dla trybu ARM) najpierw czwarty bajt, następnie trzeci, drugi i pierwszy 
(tzn \gls{endianness}).

W ten sposób bajty są wypisywane w listingach IDA:

\begin{itemize}
\item dla trybów ARM i ARM64: 4-3-2-1;
\item dla trybu Thumb: 2-1;
\item dla pary 16-bitowych instrukcji w trybie Thumb-2: 2-1-4-3.
\end{itemize}

\myindex{ARM!\Instructions!MOVW}
\myindex{ARM!\Instructions!MOVT.W}
\myindex{ARM!\Instructions!BLX}
Także widzimy, że tutaj instrukcje \TT{MOVW}, \TT{MOVT.W} i \TT{BLX} zaczynają się od \TT{0xFx}.

Jedna z Thumb-2 instrukcji to
\TT{MOVW R0, \#0x13D8}~--- ona zapisuje 16-bitową liczbę do młodszych bitów rejestru \Reg{0}, zerując starsze bity.

jeszcze jest \TT{MOVT.W R0, \#0}~--- ta instrukcja działa tak samo, jak i \TT{MOVT} z poprzedniego przykładu, ale ona nie zadziała w trybie Thumb-2.

\myindex{ARM!przełączanie trybów}
\myindex{ARM!\Instructions!BLX}
Tutaj jest wykorzystywana instrukcja \TT{BLX} zamiast \TT{BL}.
Różnica polega na tym, że oprócz zapisania adresu powrotu do rejestru \ac{LR} i przekazania zarządzania 
do f-cji \puts, odbywa się zmiana trybu procesora z Thumb/Thumb-2 na tryb ARM (lub wstecz).
Tutaj jest to niezbędne dlatego, że instrukcja (ona jest zakodowana w trybie ARM) wygląda tak:

\begin{lstlisting}[style=customasmARM]
__symbolstub1:00003FEC _puts           ; CODE XREF: _hello_world+E
__symbolstub1:00003FEC 44 F0 9F E5     LDR  PC, =__imp__puts
\end{lstlisting}

Jest to zwykłe przejście na miejsce, w którym jest zapisany adres \puts w segmencie importów.
Można zadać pytanie: dlaczego nie można wywołać \puts od razu w tym miejscu kodu w którym jest to potrzebne?
Jest to niewygodne, z racji oszczędzania miejsca.

\myindex{Biblioteki łączone dynamicznie}
Praktycznie każdy program korzysta z zewnętrznych bibliotek łączonych dynamicznie (czy to będzie DLL w Windows, .so w *NIX 
czy .dylib w \MacOSX).
W bibliotekach dynamicznych znajdują się często wykorzystywane funkcje biblioteczne, w tym standardowa f-cja biblioteki C \puts.

\myindex{Relocation}
W wykonywalnym pliku binarnym 
(Windows PE .exe, ELF lub Mach-O) istnieje segment importów, lista symboli (funkcji lub zmiennych globalnych) importowanych z modułów zewnętrznych i, również, nazwy tych modułów.
Program rozruchowy ładuje niezbędne moduły i, iterując po symbolach zaimportowanych w module głównym, ustawia rzeczywiste adresy każdego z symboli.
W naszym przypadku, \IT{\_\_imp\_\_puts} 
jest zmienną 32-bitową, gdzie program rozruchowy wpiszę adres rzeczywisty tej f-cji w bibliotece zewnętrznej. 
Czyli instrukcja \TT{LDR} po prostu bierze 32-bitową wartość z tej zmiennej, i, zapisując ją do rejestru \ac{PC}, przekazuje tam zarządzanie.
Żeby zmniejszyć czas działania programu rozruchowego, trzeba sprawić aby adres zapisywał się tylko raz do specjalnie przydzielonego miejsca.

\myindex{thunk-функции}
Do tego, jak się już upewniliśmy, zapisywanie 32-bitowej liczby do rejestru jest niemożliwe bez odwoływań się do pamięci.
Także najbardziej optymalnym rozwiązaniem jest przydzielenie osobnej f-cji, pracującej w trybie ARM, 
jedynym celem której jest przekazywanie zarządzania dalej, do bilioteki dynamicznie łączonej, a następnie, odwoływanie się do tej któtkiej f-cji (tzw \glslink{thunk function}{thunk-funkcja}) z Thumb-kodu.

\myindex{ARM!\Instructions!BL}
A propos, w poprzednim przykładzie (skompilowanym dla trybu ARM), przejście za pomocą instrukcji \TT{BL} prowadzi 
do właśnie takiej \glslink{thunk function}{thunk-funkcji}, lecz procesor się nie przestawia na inny tryb (stąd wynika brak \q{X} w mnemoniku instrukcji).

\myparagraph{Jeszcze o thunk-funkcjach}
\myindex{thunk-функции}

Thunk-funckje są trudne do zrozumienia przede wszystkim przez brak spójności w terminologii.
Najprościej będzie traktować je jako adaptery-przejściówki z jednego typu gniazdek na drugi.
Na przykład, adapter pozwalający wstawić do gniazdka amerykańskiego wtyczkę brytyjską i na odwrót. Thunk-funkcje również są czasami nazywane \IT{wrapper-ami}. \IT{Wrap} w języku angielskim to \IT{owinąć}, \IT{zawinąć}.
Oto jeszcze kilka definicji tych funkcji:

\begin{framed}
\begin{quotation}
“A piece of coding which provides an address:”, according to P. Z. Ingerman, 
who invented thunks in 1961 as a way of binding actual parameters to their formal 
definitions in Algol-60 procedure calls. If a procedure is called with an expression 
in the place of a formal parameter, the compiler generates a thunk which computes 
the expression and leaves the address of the result in some standard location.

\dots

Microsoft and IBM have both defined, in their Intel-based systems, a “16-bit environment” 
(with bletcherous segment registers and 64K address limits) and a “32-bit environment” 
(with flat addressing and semi-real memory management). The two environments can both be 
running on the same computer and OS (thanks to what is called, in the Microsoft world, 
WOW which stands for Windows On Windows). MS and IBM have both decided that the process 
of getting from 16- to 32-bit and vice versa is called a “thunk”; for Windows 95, 
there is even a tool, THUNK.EXE, called a “thunk compiler”.
\end{quotation}
\end{framed}
% TODO FIXME move to bibliography and quote properly above the quote
( \href{http://go.yurichev.com/17362}{The Jargon File} )

\myindex{LAPACK}
\myindex{FORTRAN}
Jeszcze jeden przykład możemy znaleźć w bibliotece LAPACK --- (``Linear Algebra PACKage'') napisanej w języku FORTRAN.
Deweloperzy \CCpp również chcą korzystać z LAPACK, ale przepisywać ją na \CCpp, a następnie wspierać kilka wersji,
jest szaleństwem.
Także istnieją krótkie f-cje w C, które są wywoływane z \CCpp{}-środowiska, które, z kolei, wywołują funkcje FORTRAN,
i prawie nic oprócz tego nie robią:

\begin{lstlisting}[style=customc]
double Blas_Dot_Prod(const LaVectorDouble &dx, const LaVectorDouble &dy)
{
    assert(dx.size()==dy.size());
    integer n = dx.size();
    integer incx = dx.inc(), incy = dy.inc();

    return F77NAME(ddot)(&n, &dx(0), &incx, &dy(0), &incy);
}
\end{lstlisting}

Takie f-cje również są nazywane ``wrappers'' (tzn ``opakowanie'').


